<template>
  <div class="signal-item">
    <el-form inline :rules="rules" :model='formData' ref='signalForm'>
      <el-form-item class="form-item" prop="signalGroup">
        <el-select v-model="formData.signalGroup" placeholder="信号来源" style="width: 110px;" @change="signalSourceChange">
          <el-option v-for="item in signalSourceOptions" :label="item.name" :value="item.key" :key="item.key"></el-option>
        </el-select>
      </el-form-item>
      <el-popover popper-class='' placement="top" width="262" :value="showSignalDetail" trigger="manual">
        <div>signalKey: {{ signalItem.signalKey }}</div>
        <div>signalId: {{ signalItem.signalId }}</div>
        <div>signalName: {{ signalItem.signalName }}</div>
        <div v-if="signalItem.interfaceBid">interfaceBid: {{ signalItem.interfaceBid }}</div>
        <div v-if="signalItem.serviceBid">serviceBid: {{ signalItem.serviceBid }}</div>
        <div slot="reference" @mouseenter="showSignalDetail = !!signalItem.signalKey" @mouseleave='showSignalDetail = false' @click="showSignalDetail = false" style="display: inline-block">
          <el-form-item class="form-item" prop="metaModelId" style="width: 144px">
            <treeselect v-model="formData.metaModelId" :options="signalListOptions" :normalizer="normalizer" @select="signalChange" :disableFuzzyMatching="true" :clearable="false" placeholder="请选择信号" :disable-branch-nodes="true" :maxHeight='240'/>
          </el-form-item>
        </div>
      </el-popover>
      <el-form-item class="form-item" prop="operator">
        <el-select v-model="formData.operator" placeholder="请选择操作符" @change="changeOperator">
          <el-option v-for="item in signalItem.symbols" :label="item.name" :value="item.key" :key="item.key"></el-option>
        </el-select>
      </el-form-item>
      <div v-if="['()', '[]'].includes(formData.operator)" class="form-item area-form">
        <el-popover v-if="componentsProps[paramKey] && componentsProps[paramKey].widgetClassName === 'Slider'" popper-class='signal-popper' placement="bottom" width="262" trigger="click">
          <el-slider
            v-model="formData.value"
            :min='signalItem.spec.min !== undefined ? signalItem.spec.min : componentsProps[paramKey].min'
            :max='signalItem.spec.max !== undefined ? signalItem.spec.max : componentsProps[paramKey].max'
            :show-stops='componentsProps[paramKey].showStops'
            :step='componentsProps[paramKey].step'></el-slider>
          <el-form-item slot="reference" class="area-item" prop="value" :rules="rules.inputValue">
            <el-input :value="formData.value" ref="signalInput"></el-input>
          </el-form-item>
        </el-popover>
        <el-form-item v-else prop="value" class="area-item" :rules="rules.inputValue">
          <el-input-number v-model="formData.value" :controls='false' :min='signalItem.spec.min' :max='signalItem.spec.max' :precision="componentsProps[paramKey] ? componentsProps[paramKey].precision : undefined" class="input-number"></el-input-number>
        </el-form-item>
        <span class="mid-line"> - </span>
        <el-popover v-if="componentsProps[paramKey] && componentsProps[paramKey].widgetClassName === 'Slider'" popper-class='signal-popper' placement="bottom" width="262" trigger="click">
          <el-slider
            v-model="formData.maxValue"
            :min='signalItem.spec.min !== undefined ? signalItem.spec.min : componentsProps[paramKey].min'
            :max='signalItem.spec.max !== undefined ? signalItem.spec.max : componentsProps[paramKey].max'
            :show-stops='componentsProps[paramKey].showStops'
            :step='componentsProps[paramKey].step'></el-slider>
          <el-form-item slot="reference" class="area-item" prop="maxValue" :rules="rules.inputValue">
            <el-input :value="formData.maxValue" ref="signalInput"></el-input>
          </el-form-item>
        </el-popover>
        <el-form-item v-else prop="maxValue" class="area-item" :rules="rules.inputValue">
          <el-input-number v-model="formData.maxValue" :controls='false' :min='signalItem.spec.min' :max='signalItem.spec.max' :precision="componentsProps[paramKey] ? componentsProps[paramKey].precision : undefined" class="input-number"></el-input-number>
        </el-form-item>
      </div>
      <el-popover v-else-if="componentsProps[paramKey] && componentsProps[paramKey].widgetClassName === 'Radio'" popper-class='signal-popper' placement="bottom" width="262" trigger="click">
        <el-radio-group v-model="formData.value">
          <el-radio v-for="item in signalItem.values" :label="item.key" :key="item.key" class="singal-value-radio-item">{{ item.name }}</el-radio>
        </el-radio-group>
        <el-form-item slot="reference" class="form-item" prop="value" :rules="rules.selectValue">
          <el-input :value="signalItem.values.find(item => item.key === formData.value) && signalItem.values.find(item => item.key === formData.value).name" ref="signalInput"></el-input>
        </el-form-item>
      </el-popover>
      <el-popover v-else-if="componentsProps[paramKey] && componentsProps[paramKey].widgetClassName === 'RadioButton'" popper-class='signal-popper' placement="bottom" width="262" trigger="click">
        <el-radio-group v-model="formData.value" :fill='componentsProps[paramKey].radioGroup_fill'>
          <el-radio-button v-for="item in signalItem.values" :label="item.key" :key="item.key">{{ item.name }}</el-radio-button>
        </el-radio-group>
        <el-form-item slot="reference" class="form-item" prop="value" :rules="rules.selectValue">
          <el-input :value="signalItem.values.find(item => item.key === formData.value) && signalItem.values.find(item => item.key === formData.value).name" ref="signalInput"></el-input>
        </el-form-item>
      </el-popover>
      <el-popover v-else-if="componentsProps[paramKey] && componentsProps[paramKey].widgetClassName === 'Slider'" popper-class='signal-popper' placement="bottom" width="262" trigger="click">
        <el-slider
          v-model="formData.value"
          :min='signalItem.spec.min !== undefined ? signalItem.spec.min : componentsProps[paramKey].min'
          :max='signalItem.spec.max !== undefined ? signalItem.spec.max : componentsProps[paramKey].max'
          :show-stops='componentsProps[paramKey].showStops'
          :step='componentsProps[paramKey].step'></el-slider>
        <el-form-item slot="reference" class="form-item" prop="value" :rules="rules.inputValue">
          <el-input :value="formData.value" ref="signalInput"></el-input>
          <el-popover v-if="signalItem.spec.discreteStr" placement="bottom-end" width="200" trigger="hover" :content="signalItem.spec.discreteStr" class="input-description" popper-class='desc-poper'>
            <svg-icon slot="reference" icon-class="说明"/>
          </el-popover>
        </el-form-item>
      </el-popover>
      <el-popover v-else-if="componentsProps[paramKey] && componentsProps[paramKey].widgetClassName === 'Switch'" popper-class='signal-popper' placement="bottom" width="262" trigger="click">
        <el-switch
          v-model="formData.value"
          :active-text="signalItem.values.find(item => item.key === 'true').name"
          :inactive-text="signalItem.values.find(item => item.key === 'false').name"
          :active-value='componentsProps[paramKey].activeValue'
          :inactive-value='componentsProps[paramKey].inactiveValue'
          :active-color='componentsProps[paramKey].activeColor'
          :inactive-color='componentsProps[paramKey].inactiveColor'>
        </el-switch>
        <el-form-item slot="reference" class="form-item" prop="value" :rules="rules.selectValue">
          <el-input :value="signalItem.values.find(item => item.key === formData.value) && signalItem.values.find(item => item.key === formData.value).name" ref="signalInput"></el-input>
        </el-form-item>
      </el-popover>
      <el-form-item v-else-if="componentsProps[paramKey] && componentsProps[paramKey].widgetClassName === 'ColorPicker'" class="form-item" prop="value" :rules="rules.selectValue">
        <el-color-picker v-model="formData.value"></el-color-picker>
      </el-form-item>
      <el-form-item v-else-if="signalItem.values.length > 0" class="form-item" prop="value" :rules="rules.selectValue">
        <el-select v-model="formData.value" :filterable='componentsProps[paramKey] ? componentsProps[paramKey].filterable : undefined'>
          <el-option v-for="item in signalItem.values" :label="item.name" :value="item.key" :key="item.key"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item v-else-if='signalItem.dataType === "String"' class="form-item" prop="value" :rules="rules.inputValue">
        <el-input v-model="formData.value" class="input-number" placeholder="请输入"></el-input>
        <el-popover v-if="signalItem.spec.discreteStr" placement="bottom-end" width="200" trigger="hover" :content="signalItem.spec.discreteStr" class="input-description" popper-class='desc-poper'>
          <svg-icon slot="reference" icon-class="说明"/>
        </el-popover>
      </el-form-item>
      <el-form-item v-else class="form-item" prop="value" :rules="rules.inputValue">
        <el-input-number v-model="formData.value" :controls='false' :min='signalItem.spec.min' :max='signalItem.spec.max' :precision="componentsProps[paramKey] ? componentsProps[paramKey].precision : undefined" class="input-number" placeholder="请输入"></el-input-number>
        <el-popover v-if="signalItem.spec.discreteStr" placement="bottom-end" width="200" trigger="hover" :content="signalItem.spec.discreteStr" class="input-description" popper-class='desc-poper'>
          <svg-icon slot="reference" icon-class="说明"/>
        </el-popover>
      </el-form-item>
      <div class="tool-bar">
        <svg-icon :icon-class="`参数${formData.openParam.isOpen ? '已' : '未'}开放`" :className="`${formData.openParam.isOpen} signal-open`" @click="paramOpen"/>
        <svg-icon icon-class="删除" className="signal-open" @click="deleteHandler"/>
      </div>
    </el-form>
    <ParamOpen :show.sync='showParamOpen' :openParam.sync='formData.openParam' :signalItem='signalItem' ref='paramOpen'></ParamOpen>
  </div>
</template>

<script>
import { deepClone } from '@/utils/helper/jsUtil'
import Platform from '@/utils/platform'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import SceneNodeApi from '@/api/ruleNode/sceneNode'
import { signalSource } from '../sceneNode.model'
import { adapterSignalItemData, adapterSignalList, adapterSignalItemKey, formatSignalList, addStruct, generatorTreeSelectData, formatComponentsProp } from '../sceneNode.util'
import ParamOpen from './paramOpen'
import { mapState, mapActions } from 'vuex'

export default {
  name: 'SignalListItem',
  components: {
    ParamOpen, Treeselect
  },
  data() {
    return {
      formData: {
        signalGroup: '',
        signalName: '',
        signalId: '',
        signalKey: '',
        interfaceBid: '',
        serviceBid: '',
        optionalFlag: '',
        offset: '',
        resolution: '',
        metaModelId: null,
        operator: '',
        value: undefined,
        maxValue: undefined,
        openParam: {
          isOpen: false
        }
      },
      componentsProps: {},
      signalItem: {
        symbols: null,
        values: [],
        dataType: '',
        spec: {}
      },
      signalListData: null,
      signalListOptions: [],
      rules: {
        signalGroup: [{ required: true, message: ' ', trigger: 'change' }],
        metaModelId: [{ required: true, message: ' ', trigger: 'change' }],
        operator: [{ required: true, message: ' ', trigger: 'change' }],
        inputValue: [{ required: true, message: ' ', trigger: 'blur' }],
        selectValue: [{ required: true, message: ' ', trigger: 'change' }]
      },
      showSignalDetail: false,
      showParamOpen: false
    }
  },
  props: {
    signalData: {
      required: true
    }
  },
  async mounted() {
    if (this.signalData.signalGroup) {
      this.formData = deepClone(this.signalData)
      this.formData.openParam = this.signalData.openParam || { isOpen: false }
      const value = this.formData.value
      await this.getTreeList(this.signalData.signalGroup)
      this.formData.metaModelId = generatorTreeSelectData(this.signalData)
      this.getSignalItem(this.formData.metaModelId, this.signalData.signalGroup)
      this.$nextTick(() => { this.formData.value = value }) // 16进制转换字符串hack
    }
  },
  computed: {
    ...mapState({
      productType: state => state.product.type
    }),
    signalSourceOptions() {
      return signalSource.filter(el => el.scope.includes(this.productType))
    },
    paramKey() {
      return this.signalItem.signalKey?.split('&_&').at(-1)
    }
  },
  watch: {
    formData: {
      handler(val) {
        if (val) {
          this.$emit('change', deepClone(this.formData))
        }
      },
      deep: true
    }
  },
  methods: {
    signalSourceChange(source) {
      this.signalItem = {
        symbols: null,
        values: [],
        dataType: '',
        spec: {}
      }
      this.formData.metaModelId = null
      this.formData.operator = ''
      this.formData.value = undefined
      this.formData.openParam = { isOpen: false }

      this.getTreeList(source)
      this.$nextTick(() => { this.$refs.signalForm.clearValidate() })
    },
    async getTreeList(source) {
      if (!source) { return false }
      const res = await this.getSignal(source)
      this.signalListData = addStruct(res, source)
      const options = adapterSignalList(this.signalListData.options, source)
      this.signalListOptions = formatSignalList(options)
    },
    signalChange(signalKey) {
      this.formData.operator = ''
      this.formData.value = undefined
      this.getSignalItem(signalKey.value, this.formData.signalGroup)
      this.$nextTick(() => { this.$refs.signalForm.clearValidate() })
    },
    changeOperator() {
      this.formData.maxValue && (this.formData.maxValue = undefined)
    },
    getSignalItem(signalKey, signalGroup) {
      this.showSignalDetail = false
      const signalItem = this.signalListData.signals.find(el => adapterSignalItemKey(el, signalGroup) === signalKey)
      if (signalItem) {
        this.signalItem = adapterSignalItemData(signalItem, signalGroup)
      } else {
        this.signalItem = { symbols: null, values: [], dataType: '', spec: {} }
      }
      this.formData.signalKey = this.signalItem.signalKey
      this.formData.signalId = this.signalItem.signalId
      this.formData.interfaceBid = this.signalItem.interfaceBid
      this.formData.serviceBid = this.signalItem.serviceBid
      this.formData.optionalFlag = this.signalItem.optionalFlag
      this.formData.signalName = this.signalItem.signalName
      this.formData.offset = this.signalItem.spec.offset
      this.formData.resolution = this.signalItem.spec.resolution
      this.getS2_2()
    },
    // 获取S2-2对应信号的小组件配置信息
    async getS2_2() {
      const param = {
        id: this.signalItem.signalId,
        terminalType: 0,
        metamodelParams: [{
          paramDataType: this.signalItem.dataType, paramKey: this.paramKey
        }]
      }
    },
    paramOpen() {
      if (!this.formData.metaModelId) { return false }
      if (this.formData.optionalFlag === 1) { return this.$message({ type: 'warning', message: '选装信号不支持参数开放' }) }
      this.showParamOpen = !this.showParamOpen
      if (!this.showParamOpen) {
        this.$refs.paramOpen.resetForm()
      }
    },
    normalizer(node) {
      const rtn = {
        id: node.id || node.value,
        label: node.name || node.label
      }
      if (node.children && node.children.length > 0) {
        rtn.children = node.children
      } else {
        delete node.children
      }
      return rtn
    },
    deleteHandler() {
      this.$emit('delete')
    },
    ...mapActions('signal', ['getSignal'])
  }
}
</script>

<style lang="scss" scoped>
.signal-item {
  .el-form{
    overflow: visible;
  }
  .form-item{
    margin-right: 8px;
    margin-bottom: 8px;
    &:nth-child(1) {
      width: 110px;
    }
    &:nth-child(2) {
      width: 144px;
    }
    &:nth-child(3) {
      width: 70px;
    }
    &:nth-child(4) {
      width: 130px;
      margin-right: 0;
    }
    &.area-form{
      display: inline-flex;
      vertical-align: top;
      .area-item{
        margin-bottom: 0;
        margin-right: 0;
        width: 57px;
      }
      .mid-line{
        width: 15px;
        text-align: center;
        line-height: 30px;
      }
    }
    .input-description{
      position: absolute;
      right: 4px;
      font-size: 16px;
      display: block;
      top: 0;
      line-height: 32px;
      color: #a3a3a3;
    }
  }

  .tool-bar {
    float: right;
    .signal-open{
      width: 16px;
      height: 32px;
      cursor: pointer;
      margin-left: 24px;
      margin-right: 2px;
      &:nth-child(1) {
        margin-left: 0;
      }
      &.true{
        width: 18px;
        margin-right: 0;
      }
    }
  }
}
</style>
<style lang="scss">
.signal-item .form-item .input-number{
  width: 100%;
  .el-input__inner{
    text-align: left;
  }
}
</style>
